mod result;
mod config;
mod models;
mod handler;
mod error;
mod from;

use actix_web::{HttpServer, App, web, Responder, HttpResponse};
use std::io::Result;
use self::result::Status;
use dotenv::dotenv;
use mysql_async::Pool;
use mysql_async::prelude::Queryable;
use crate::models::login;

async fn logins(db : web::Data<Pool>) -> impl Responder {
    let result = handler::select_all(db).await;
    match result {
        Ok(logins) => HttpResponse::Ok().json(logins),
        Err(_) => HttpResponse::InternalServerError().into(),
    }
}

async fn login(db : web::Data<Pool>,path :  web::Path<(i32,)>) -> impl Responder{
    let result = handler::select_one(db,path.0).await;
    match result {
        Ok(logins) => HttpResponse::Ok().json(logins),
        Err(err) => {
            println!("{:?}",err);
            HttpResponse::InternalServerError().into()},
    }
}

async fn create(db : web::Data<Pool>,info : web::Json<from::create>) -> impl Responder{
    println!("{:?}",info);
    let result = handler::create_one(db,info.0).await;

    match result {
        Ok(id) => HttpResponse::Ok().json(result::Id{id:id}),
        Err(err) => {
            println!("{:?}",err);
            HttpResponse::InternalServerError().into()},
    }
}

async fn update(db : web::Data<Pool>,info : web::Json<models::login>) -> impl Responder{
    println!("{:?}",info);
    let result = handler::updata_one(db,info.0).await;

    match result {
        Ok(id) => HttpResponse::Ok().json(result::Status{ status: 200 }),
        Err(err) => {
            println!("{:?}",err);
            HttpResponse::InternalServerError().into()},
    }
}

async fn delete(db : web::Data<Pool>,info : web::Json<from::id>) -> impl Responder{
    println!("{:?}",info);
    let result = handler::delete_one(db,info.0).await;

    match result {
        Ok(id) => HttpResponse::Ok().json(result::Status{ status: 200 }),
        Err(err) => {
            println!("{:?}",err);
            HttpResponse::InternalServerError().into()},
    }
}

#[actix_rt::main]
async fn main() -> Result<()>{
    dotenv().ok();

    let config = crate::config::Config::from_env().unwrap();
    println!("{:?}",config);

    let db = models::establish_connection(&config);

    HttpServer::new(move ||{
        App::new()
            .data(db.clone())
            .route("/logins",web::get().to(logins))
            .route("/login/{id}",web::get().to(login))
            .route("/login",web::post().to(create))
            .route("/login",web::put().to(update))
            .route("/login",web::delete().to(delete))
    })
        .bind(format!("{}:{}",config.server.host,config.server.port))?
        .run()
        .await
}